package com.haohan.cloud.scm.wms.core.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.haohan.cloud.scm.api.constant.NumberPrefixConstant;
import com.haohan.cloud.scm.api.constant.enums.common.TaskStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.common.UseStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.product.*;
import com.haohan.cloud.scm.api.constant.enums.purchase.PurchaseStatusEnum;
import com.haohan.cloud.scm.api.goods.dto.GoodsModelDTO;
import com.haohan.cloud.scm.api.manage.entity.UPassport;
import com.haohan.cloud.scm.api.product.dto.ProcessingResultDTO;
import com.haohan.cloud.scm.api.product.dto.ProcessingSourceDTO;
import com.haohan.cloud.scm.api.product.entity.ProductInfo;
import com.haohan.cloud.scm.api.product.req.ProductInfoReq;
import com.haohan.cloud.scm.api.product.req.ProductMatchSortingReq;
import com.haohan.cloud.scm.api.product.trans.ProductInfoTrans;
import com.haohan.cloud.scm.api.purchase.entity.PurchaseOrderDetail;
import com.haohan.cloud.scm.api.purchase.entity.PurchaseTask;
import com.haohan.cloud.scm.api.purchase.req.PurchaseOrderDetailReq;
import com.haohan.cloud.scm.api.purchase.req.PurchaseProductEntryReq;
import com.haohan.cloud.scm.api.purchase.req.PurchaseTaskReq;
import com.haohan.cloud.scm.api.wms.entity.*;
import com.haohan.cloud.scm.api.wms.req.*;
import com.haohan.cloud.scm.api.wms.resp.EnterDetailResp;
import com.haohan.cloud.scm.api.wms.resp.EnterWarehouseDetailResp;
import com.haohan.cloud.scm.api.wms.resp.QueryEnterDetailResp;
import com.haohan.cloud.scm.api.wms.trans.EnterWareHouseTrans;
import com.haohan.cloud.scm.api.wms.trans.EnterWarehouseDetailTrans;
import com.haohan.cloud.scm.common.tools.exception.EmptyDataException;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.common.tools.util.ScmIncrementUtil;
import com.haohan.cloud.scm.wms.core.IScmEnterWarehouseService;
import com.haohan.cloud.scm.wms.service.*;
import com.haohan.cloud.scm.wms.utils.ScmWmsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author xwx
 * @date 2019/6/13
 */
@Service
public class ScmEnterWarehouseServiceImpl implements IScmEnterWarehouseService {

    @Autowired
    @Lazy
    private ScmWmsUtils scmWmsUtils;
    @Autowired
    @Lazy
    private EnterWarehouseDetailService enterWarehouseDetailService;
    @Autowired
    @Lazy
    private EnterWarehouseService enterWarehouseService;
    @Autowired
    @Lazy
    private ScmIncrementUtil scmIncrementUtil;
    @Autowired
    @Lazy
    private PalletService palletService;
    @Autowired
    @Lazy
    private CellService cellService;
    @Autowired
    @Lazy
    private ShelfManagementService shelfManagementService;

    /**
     * 新增入库单明细 根据采购单明细
     * @param req  必须：purchaseDetailSn
     * @return
     */
    @Override
    public EnterWarehouseDetail addEnterDetailByPurchaseDetail(AddEnterDetailReq req) {
        //获取入库申请人
        UPassport uPassport = scmWmsUtils.queryUPassportById(req.getApplicantId());
        String loginName = uPassport.getLoginName();
        //关联采购单明细
        PurchaseOrderDetailReq orderDetailReq = new PurchaseOrderDetailReq();
        orderDetailReq.setPmId(req.getPmId());
        orderDetailReq.setPurchaseDetailSn(req.getPurchaseDetailSn());
        PurchaseOrderDetail purchaseOrderDetail = scmWmsUtils.fetchOrderDetail(orderDetailReq);
        //设置数据
        EnterWarehouseDetail enterWarehouseDetail = EnterWarehouseDetailTrans.trans(purchaseOrderDetail);
        //设置入库申请人
        enterWarehouseDetail.setApplicantId(req.getApplicantId());
        enterWarehouseDetail.setApplicantName(loginName);
        enterWarehouseDetailService.save(enterWarehouseDetail);
        return enterWarehouseDetail;
    }

    /**
     * 新增入库单 根据入库单明细
     * @param req  ids采购单明细编号数组/pmId/warehouseSn
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createEnterWarehouse(CreateEnterWarehouseReq req) {
        //生成入库单编号
        String sn = scmIncrementUtil.inrcSnByClass(EnterWarehouse.class, NumberPrefixConstant.ENTER_WAREHOUSE_SN_PRE);

        EnterWarehouseDetail warehouseDetail = new EnterWarehouseDetail();
        warehouseDetail.setPmId(req.getPmId());
        //循环插入入库单编号
        for (String purchaseDetailSn : req.getIds()) {
            warehouseDetail.setEnterWarehouseDetailSn(purchaseDetailSn);
            //查询入库单明细
            EnterWarehouseDetail one = enterWarehouseDetailService.getOne(Wrappers.query(warehouseDetail));
            one.setEnterWarehouseSn(sn);
            //判断仓库编号是否一致
            if (!StrUtil.equals(one.getWarehouseSn(),req.getWarehouseSn())){
                throw new ErrorDataException("仓库编号不一致");
            }
            //修改入库单明细
            EnterWarehouseDetail enterWarehouseDetail = new EnterWarehouseDetail();
            enterWarehouseDetail.setId(one.getId());
            enterWarehouseDetail.setEnterWarehouseSn(sn);
            enterWarehouseDetailService.updateById(enterWarehouseDetail);
        }
        //新建入库单
        EnterWarehouse enterWarehouse = EnterWarehouseDetailTrans.enterWarehouseTrans(req);
        enterWarehouse.setEnterWarehouseSn(sn);
        return enterWarehouseService.save(enterWarehouse);
    }

    /**
     * 新增入库单 入库存储
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean warehouseStorage(WarehouseStorageReq req) {
        //生成入库单编号
        String sn = scmIncrementUtil.inrcSnByClass(EnterWarehouse.class, NumberPrefixConstant.ENTER_WAREHOUSE_SN_PRE);
        //设置新增入库单明细参数
        AddEnterDetailReq addEnterDetailReq = new AddEnterDetailReq();
        addEnterDetailReq.setPmId(req.getPmId());
        addEnterDetailReq.setApplicantId(req.getApplicantId());
        addEnterDetailReq.setApplicantName(req.getApplicantName());
        for (String purchaseDetailSn : req.getIds()) {
            addEnterDetailReq.setPurchaseDetailSn(purchaseDetailSn);
            //获取托盘
            GainPalletReq gainPalletReq = new GainPalletReq();
            gainPalletReq.setPmId(req.getPmId());
            gainPalletReq.setWarehouseSn(req.getWarehouseSn());
            Pallet pallet = gainPallet(gainPalletReq);
            //获取货位
            Cell cell = gainCell(req.getWarehouseSn(), req.getPmId());
            //新增入库单明细
            EnterWarehouseDetail warehouseDetail = addEnterDetailByPurchaseDetail(addEnterDetailReq);
            //修改入库单明细
            EnterWarehouseDetail enterWarehouseDetail = new EnterWarehouseDetail();
            enterWarehouseDetail.setId(warehouseDetail.getId());
            enterWarehouseDetail.setEnterWarehouseSn(sn);
            enterWarehouseDetail.setPalletSn(pallet.getPalletSn());
            enterWarehouseDetail.setShelfSn(cell.getShelfSn());
            enterWarehouseDetail.setCellSn(cell.getCellSn());
            enterWarehouseDetailService.updateById(enterWarehouseDetail);
            //修改托盘
            Pallet updatePallet = new Pallet();
            updatePallet.setId(pallet.getId());
            updatePallet.setCellSn(cell.getCellSn());
            updatePallet.setStorageStatus(StorageStatusEnum.occupied);
            palletService.updateById(updatePallet);
        }
        //新增入库单
        CreateEnterWarehouseReq createEnterWarehouseReq = new CreateEnterWarehouseReq();
        createEnterWarehouseReq.setBatchNumber(req.getBatchNumber());
        createEnterWarehouseReq.setPmId(req.getPmId());
        createEnterWarehouseReq.setWarehouseSn(req.getWarehouseSn());
        createEnterWarehouseReq.setPurchaseSn(req.getPurchaseSn());
        EnterWarehouse enterWarehouse = EnterWarehouseDetailTrans.enterWarehouseTrans(createEnterWarehouseReq);
        enterWarehouse.setEnterWarehouseSn(sn);
        return enterWarehouseService.save(enterWarehouse);
    }

    /**
     * 获取货位
     * @param warehouseSn
     * @param pmId
     * @return
     */
    public Cell gainCell(String warehouseSn,String pmId){
        Cell cell = new Cell();
        cell.setWarehouseSn(warehouseSn);
        cell.setPmId(pmId);
//        cell.setStorageStatus(StorageStatusEnum.idle);
        cell.setUseStatus(UseStatusEnum.enabled);
        List<Cell> list = cellService.list(Wrappers.query(cell));
        return list.get(0);
    }

    /**
     * 获取托盘
     * @param req
     * @return
     */
    @Override
    public Pallet gainPallet(GainPalletReq req) {
        //查询未使用的托盘列表
        Pallet palletReq = new Pallet();
        palletReq.setPmId(req.getPmId());
        palletReq.setWarehouseSn(req.getWarehouseSn());
        palletReq.setStorageStatus(StorageStatusEnum.idle);
        palletReq.setUseStatus(UseStatusEnum.enabled);
        List<Pallet> list = palletService.list(Wrappers.query(palletReq));
        //没有空闲的托盘就新建托盘
        if (CollUtil.isEmpty(list)){
            Pallet pallet = new Pallet();
            pallet.setPmId(req.getPmId());
            pallet.setWarehouseSn(req.getWarehouseSn());
            pallet.setPalletPutType(PalletPutTypeEnum.good_location);
            pallet.setUseStatus(UseStatusEnum.enabled);
            pallet.setStorageStatus(StorageStatusEnum.idle);
            palletService.save(pallet);
            return pallet;
        }else {
            //有空闲的托盘就用第一个
            Pallet pallet = list.get(0);
            return pallet;
        }

    }

    /**
     * 货品入库操作 货品放置在 托盘 上
     * @param req  必须：pmId/productSn/palletSn
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Pallet productEnter(ProductEnterReq req) {
        ProductInfoReq productInfoReq = new ProductInfoReq();
        productInfoReq.setProductSn(req.getProductSn());
        productInfoReq.setPmId(req.getPmId());
        //判断productSn是否能查回货品信息
        scmWmsUtils.fetchProductInfo(productInfoReq);
        //查询托盘
        Pallet pallet = scmWmsUtils.fetchPalletStatus(req.getPalletSn());
        pallet.setProductSn(req.getProductSn());
        pallet.setStorageStatus(StorageStatusEnum.occupied);
        pallet.setPalletPutType(req.getPalletPutType());
        pallet.setPmId(req.getPmId());
        palletService.updateById(pallet);

        return pallet;
    }

    /**
     * 新增入库单(入库单明细) 根据货品信息
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createEnterWarehouseByProductInfo(CreateEnterByProductInfoReq req) {
        //获取入库申请人
        UPassport uPassport = scmWmsUtils.queryUPassportById(req.getApplicantId());
        String loginName = uPassport.getLoginName();
        //创建入库单
        EnterWarehouse enterWarehouse = new EnterWarehouse();
        //生成入库单编号
        String sn = scmIncrementUtil.inrcSnByClass(EnterWarehouse.class, NumberPrefixConstant.ENTER_WAREHOUSE_SN_PRE);
        for (ProductInfo productInfo : req.getList()) {
            //设置入库单明细数据
            EnterWarehouseDetail enterDetail = EnterWarehouseDetailTrans.productInfoTrans(productInfo);
            enterDetail.setEnterWarehouseSn(sn);
            enterDetail.setApplicantId(req.getApplicantId());
            enterDetail.setApplicantName(loginName);
            enterWarehouseDetailService.save(enterDetail);
            //将入库单编号填入货品信息中
            productInfo.setEnterWarehouseSn(sn);
            //修改货品信息
            scmWmsUtils.updateProductInfo(productInfo);
        }
        enterWarehouse.setEnterWarehouseSn(sn);
        enterWarehouse.setApplyTime(LocalDateTime.now());
        enterWarehouse.setEnterStatus(EnterStatusEnum.handle);
        enterWarehouse.setStorageType(StorageTypeEnum.enterwarehouse);
        return enterWarehouseService.save(enterWarehouse);
    }

    /**
     * 货品上架
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean productPutShelf(ProductPutShelfReq req) {
        //获取操作人对象
        UPassport uPassport = scmWmsUtils.queryUPassportById(req.getOperatorId());
        //查询货位
        Cell cell = scmWmsUtils.fetchCellStatus(req.getPmId(), req.getCellSn());
        cell.setStorageStatus(StorageStatusEnum.occupied);
        cellService.updateById(cell);
        //获取货物托盘
        Pallet pallet = req.getPallet();
        //将货位编号存入托盘
        pallet.setCellSn(req.getCellSn());
        palletService.updateById(pallet);
        //获取货品信息
        ProductInfoReq productInfoReq = new ProductInfoReq();
        productInfoReq.setPmId(req.getPmId());
        productInfoReq.setProductSn(req.getProductSn());
        ProductInfo productInfo = scmWmsUtils.fetchProductInfo(productInfoReq);
        //创建货品上架记录
        ShelfManagement shelfManagement = EnterWarehouseDetailTrans.putawayTrans(productInfo, req);
        shelfManagement.setWarehouseSn(cell.getWarehouseSn());
        shelfManagement.setShelfSn(cell.getShelfSn());
        shelfManagement.setOperatorId(req.getOperatorId());
        shelfManagement.setOperatorName(uPassport.getLoginName());
        return shelfManagementService.save(shelfManagement);
    }

    /**
     * 货品下架(货位、货品数量全下)
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean productRemoveShelf(ProductRemoveShelfReq req) {
        //获取操作人对象
        UPassport uPassport = scmWmsUtils.queryUPassportById(req.getOperatorId());
        //查询货品信息
        ProductInfoReq productInfoReq = new ProductInfoReq();
        productInfoReq.setPmId(req.getPmId());
        productInfoReq.setProductSn(req.getProductSn());
        ProductInfo productInfo = scmWmsUtils.fetchProductInfo(productInfoReq);
        //查询托盘信息
        Pallet pallet = scmWmsUtils.queryPallet(req.getPmId(), req.getProductSn());
        //查询货位信息
        Cell cell = scmWmsUtils.queryCell(pallet.getCellSn());
        //创建货品下架记录
        ShelfManagement shelfManagement = EnterWarehouseDetailTrans.removeShelfTrans(productInfo, cell, pallet);
        shelfManagement.setOperatorId(req.getOperatorId());
        shelfManagement.setOperatorName(uPassport.getLoginName());
        shelfManagement.setProductNumber(productInfo.getProductNumber());
        //修改货位信息
        cell.setStorageStatus(StorageStatusEnum.idle);
        //修改托盘信息
        pallet.setCellSn(null);
        palletService.updateById(pallet);
        cellService.updateById(cell);

        return shelfManagementService.save(shelfManagement);
    }

    /**
     * 货品下架(货位、货品数量部分下架)
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean productRemoveSection(ProductRemoveSectionReq req) {
        //获取操作人对象
        UPassport uPassport = scmWmsUtils.queryUPassportById(req.getOperatorId());
        //拆分货品
        ProcessingSourceDTO sourceDTO = new ProcessingSourceDTO();
        sourceDTO.setSourceProductSn(req.getSourceProductSn());
        sourceDTO.setSubProductNum(req.getSubProductNum());
        ProcessingResultDTO resultDTO = scmWmsUtils.fetchProductPeeling(sourceDTO);
        //下架货品
        ProductInfo removeProduct = resultDTO.getSourceProduct();
        //剩余货品
        ProductInfo surplusProduct = resultDTO.getLossProduct();
        //查询原托盘信息
        Pallet pallet = scmWmsUtils.queryPallet(req.getPmId(), req.getSourceProductSn());
        //查询货位信息
        Cell cell = scmWmsUtils.queryCell(pallet.getCellSn());
        //创建货品下架记录
        ShelfManagement shelfManagement = EnterWarehouseDetailTrans.removeShelfTrans(removeProduct, cell, pallet);
        shelfManagement.setOperatorId(req.getOperatorId());
        shelfManagement.setOperatorName(uPassport.getLoginName());
        shelfManagement.setProductNumber(req.getSubProductNum());
        //修改原托盘信息
        pallet.setProductSn(surplusProduct.getProductSn());
        //获取空托盘 存放下架货品
        Pallet newPallet = scmWmsUtils.fetchPalletStatus(req.getTargetPalletSn());
        newPallet.setProductSn(removeProduct.getProductSn());
        newPallet.setPmId(removeProduct.getPmId());
        newPallet.setPalletPutType(PalletPutTypeEnum.good_location);
        newPallet.setStorageStatus(StorageStatusEnum.occupied);
        //修改下架货品的托盘
        palletService.updateById(newPallet);
        palletService.updateById(pallet);
        scmWmsUtils.addProductInfo(removeProduct);
        //修改剩余货品信息
        surplusProduct.setProductQuality(ProductQialityEnum.normal);
        scmWmsUtils.addProductInfo(surplusProduct);

        return shelfManagementService.save(shelfManagement);
    }

    /**
     * 采购明细货品 实际入库
     * @param req 必需 purchaseDetailSn /realBuyNum
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean purchaseProductEntry(PurchaseProductEntryReq req) {
        String detailSn = req.getPurchaseDetailSn();
        BigDecimal realBuyNum = req.getRealBuyNum();
        String pmId = req.getPmId();
        //检查采购任务  执行中
        PurchaseTaskReq taskReq = new PurchaseTaskReq();
        taskReq.setPmId(pmId);
        taskReq.setId(req.getTaskId());
        taskReq.setTaskStatus(TaskStatusEnum.doing);
        PurchaseTask task = scmWmsUtils.fetchPurchaseTask(taskReq);
        //查询采购单明细
        PurchaseOrderDetailReq detailReq = new PurchaseOrderDetailReq();
        detailReq.setPmId(pmId);
        detailReq.setPurchaseDetailSn(detailSn);
        detailReq.setPurchaseStatus(PurchaseStatusEnum.haveSales);
        PurchaseOrderDetail orderDetail = scmWmsUtils.fetchOrderDetail(detailReq);
        // 查询入库单明细
        QueryWrapper<EnterWarehouseDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(EnterWarehouseDetail::getPurchaseDetailSn, detailSn)
                .eq(EnterWarehouseDetail::getEnterStatus, EnterStatusEnum.handle);
        EnterWarehouseDetail enterDetail = enterWarehouseDetailService.getOne(queryWrapper);
        if(null == enterDetail){
            return false;
        }

        // 根据新入库货品 匹配分拣
        ProductMatchSortingReq info = new ProductMatchSortingReq();
        info.setPmId(pmId);
        info.setRealBuyNum(realBuyNum);
        info.setPurchaseDetailSn(detailSn);
        ProductInfo productInfo = scmWmsUtils.enterProductMatchSorting(info);

        // 修改 入库单明细
        EnterWarehouseDetail updateEnterDetail = new EnterWarehouseDetail();
        updateEnterDetail.setId(enterDetail.getId());
        updateEnterDetail.setProductNumber(realBuyNum);
        updateEnterDetail.setProductSn(productInfo.getProductSn());
        updateEnterDetail.setEnterStatus(EnterStatusEnum.accept);
        updateEnterDetail.setAuditTime(LocalDateTime.now());
        enterWarehouseDetailService.updateById(updateEnterDetail);

        // 修改 采购明细 数量
        PurchaseOrderDetail purchaseOrderDetail = new PurchaseOrderDetail();
        purchaseOrderDetail.setId(orderDetail.getId());
        purchaseOrderDetail.setRealBuyNum(realBuyNum);
        purchaseOrderDetail.setPurchaseStatus(PurchaseStatusEnum.finish);
        scmWmsUtils.updateOrderDetail(purchaseOrderDetail);
        //修改任务状态 已完成
        PurchaseTask purchaseTask = new PurchaseTask();
        purchaseTask.setId(task.getId());
        purchaseTask.setTaskStatus(TaskStatusEnum.finish);
        scmWmsUtils.updatePurchaseTask(purchaseTask);
        return true;
    }

    /**
     * 新增入库单（入库单明细）根据采购单明细
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean enterWarehouseByOrderDetail(EnterWarehouseByOrderDetailReq req) {
        //生成入库单号
        String sn = scmIncrementUtil.inrcSnByClass(EnterWarehouseDetail.class, NumberPrefixConstant.ENTER_WAREHOUSE_SN_PRE);
        //查询采购单明细列表
        PurchaseOrderDetailReq detailReq = new PurchaseOrderDetailReq();
        detailReq.setPmId(req.getPmId());
        detailReq.setPurchaseSn(req.getPurchaseSn());
        List<PurchaseOrderDetail> detailList = scmWmsUtils.fetchOrderDetailList(detailReq);
        //创建入库单
        EnterWarehouse enterWarehouse = EnterWareHouseTrans.enterWarehouseTrans(req);
        enterWarehouse.setEnterWarehouseSn(sn);

        for (PurchaseOrderDetail orderDetail : detailList) {
            //查询货品信息
            ProductInfoReq infoReq = new ProductInfoReq();
            infoReq.setPmId(orderDetail.getPmId());
            infoReq.setPurchaseDetailSn(orderDetail.getPurchaseDetailSn());
            ProductInfo productInfo = scmWmsUtils.fetchProductInfo(infoReq);
            //创建入库单明细
            EnterWarehouseDetail detail = EnterWarehouseDetailTrans.enterWarehouseDetailTrans(orderDetail, productInfo);
            detail.setEnterWarehouseSn(sn);
            enterWarehouseDetailService.save(detail);
        }
        enterWarehouseService.save(enterWarehouse);
        return true;
    }

    /**
     * 查询入库单明细（包含货品信息）根据入库单号
     * @param req
     * @return
     */
    @Override
    public List<EnterWarehouseDetailResp> queryEnterWarehouseDetail(QueryEnterWarehouseDetailReq req) {
        //查询入库单明细
        EnterWarehouseDetail detail = new EnterWarehouseDetail();
        detail.setPmId(req.getPmId());
        detail.setEnterWarehouseSn(req.getEnterWarehouseSn());
        List<EnterWarehouseDetail> list = enterWarehouseDetailService.list(Wrappers.query(detail));
        if(list.isEmpty()){
            throw new EmptyDataException();
        }
        List<EnterWarehouseDetailResp> respList = new ArrayList<>();
        for (EnterWarehouseDetail enterWarehouseDetail : list) {
            //查询货品信息
            ProductInfoReq infoReq = new ProductInfoReq();
            infoReq.setProductSn(enterWarehouseDetail.getProductSn());
            ProductInfo info = scmWmsUtils.fetchProductInfo(infoReq);
            EnterWarehouseDetailResp resp = EnterWarehouseDetailTrans.respTrans(enterWarehouseDetail, info);
            respList.add(resp);
        }
        return respList;
    }

    /**
     * 根据商品创建入库单、入库单明细明细、货品信息
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createEnterWarehouse(CreateEnterWarehouseDetailReq req) {
        String pmId = req.getPmId();
        //生成入库单号
        String sn = scmIncrementUtil.inrcSnByClass(EnterWarehouseDetail.class, NumberPrefixConstant.ENTER_WAREHOUSE_SN_PRE);
        //创建入库单
        EnterWarehouse enterWarehouse = EnterWarehouseDetailTrans.createEnterWarehouseTrans(req);
        enterWarehouse.setEnterWarehouseSn(sn);
        for (GoodsModelReq goodsModelReq : req.getList()) {
            //查询商品详情DTO
            GoodsModelDTO dto = scmWmsUtils.fetchGoodsModel(goodsModelReq.getGoodsModelId());
            //生成货品单号
            String productSn = scmIncrementUtil.inrcSnByClass(ProductInfo.class, NumberPrefixConstant.PRODUCT_INFO_SN_PRE);
            //创建货品信息
            ProductInfo info = ProductInfoTrans.createProductInfo(dto);
            info.setPmId(pmId);
            info.setEnterWarehouseSn(sn);
            info.setProductNumber(goodsModelReq.getProductNumber());
            info.setProductSn(productSn);
            //创建入库单明细
            EnterWarehouseDetail detail = EnterWarehouseDetailTrans.createEnterWarehouseDetailTrans(req.getWarehouseSn(),dto);
            detail.setEnterWarehouseSn(sn);
            detail.setProductSn(productSn);
            detail.setProductNumber(goodsModelReq.getProductNumber());
            detail.setPmId(pmId);
            scmWmsUtils.addProductInfo(info);
            enterWarehouseDetailService.save(detail);
        }
        enterWarehouseService.save(enterWarehouse);
        return true;
    }

    /**
     * 修改入库单明细和货品信息
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateEnterWarehouseDetail(UpdateEnterWarehouseDetailReq req) {
        String pmId = req.getPmId();
        for (ParamReq paramReq : req.getList()) {
            //判断入库单明细是否存在
            EnterWarehouseDetail detail = new EnterWarehouseDetail();
            detail.setPmId(pmId);
            detail.setGoodsModelId(paramReq.getEnterWarehouseDetailSn());
            EnterWarehouseDetail one = enterWarehouseDetailService.getOne(Wrappers.query(detail));
            if (null==one){
                //生成货品单号
                String productSn = scmIncrementUtil.inrcSnByClass(ProductInfo.class, NumberPrefixConstant.PRODUCT_INFO_SN_PRE);
                //查询商品规格
                GoodsModelDTO goodsModelDTO = scmWmsUtils.fetchGoodsModel(paramReq.getGoodsModelId());
                //新增货品信息
                ProductInfo info = ProductInfoTrans.createProductInfo(goodsModelDTO);
                info.setPmId(pmId);
                info.setProductNumber(paramReq.getProductNumber());
                info.setEnterWarehouseSn(req.getEnterWarehouseSn());
                info.setProductSn(productSn);
                scmWmsUtils.addProductInfo(info);
                //创建入库单明细
                EnterWarehouseDetail enterWarehouseDetail = EnterWarehouseDetailTrans.createEnterWarehouseDetailTrans(req.getWarehouseSn(),goodsModelDTO);
                enterWarehouseDetail.setEnterWarehouseSn(req.getEnterWarehouseSn());
                enterWarehouseDetail.setProductSn(productSn);
                enterWarehouseDetail.setProductNumber(paramReq.getProductNumber());
                enterWarehouseDetailService.save(enterWarehouseDetail);
            }else {
                //修改入库单明细
                EnterWarehouseDetail enterWarehouseDetail = new EnterWarehouseDetail();
                enterWarehouseDetail.setId(one.getId());
                one.setProductNumber(paramReq.getProductNumber());
                enterWarehouseDetailService.updateById(enterWarehouseDetail);
                //查询货品信息
                ProductInfoReq infoReq = new ProductInfoReq();
                infoReq.setPmId(pmId);
                infoReq.setProductSn(one.getProductSn());
                ProductInfo productInfo = scmWmsUtils.fetchProductInfo(infoReq);
                ProductInfo info = new ProductInfo();
                info.setId(productInfo.getId());
                info.setProductNumber(paramReq.getProductNumber());
                scmWmsUtils.updateProductInfo(info);

            }
        }
        return true;
    }

    /**
     * 查寻订单退货入库单详情
     * @param req
     * @return
     */
    @Override
    public QueryEnterDetailResp queryEnterDetail(EnterWarehouseReq req) {
        EnterWarehouse warehouse = new EnterWarehouse();
        BeanUtil.copyProperties(req,warehouse);
        EnterWarehouse one = enterWarehouseService.getOne(Wrappers.query(warehouse));
        if(ObjectUtil.isNull(one)){
            throw new EmptyDataException();
        }
        QueryWrapper<EnterWarehouseDetail> query = new QueryWrapper<>();
        query.lambda()
                .eq(EnterWarehouseDetail::getPmId,one.getPmId())
                .eq(EnterWarehouseDetail::getEnterWarehouseSn,one.getEnterWarehouseSn());
        List<EnterWarehouseDetail> list = enterWarehouseDetailService.list(query);
        List<EnterDetailResp> resp = new ArrayList<>();
        if(list.isEmpty()){
            throw new EmptyDataException();
        }
        list.forEach( l -> {
            ProductInfoReq q = new ProductInfoReq();
            q.setProductSn(l.getProductSn());
            ProductInfo info = scmWmsUtils.fetchProductInfo(q);
            EnterDetailResp r = new EnterDetailResp();
            BeanUtil.copyProperties(l,r);
            r.setProductName(info.getProductName());
            resp.add(r);
        });
        QueryEnterDetailResp res = new QueryEnterDetailResp();
        BeanUtil.copyProperties(one,res);
        res.setList(resp);
        return res;
    }

    /**
     * 编辑入库单
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean editEnterWarehouse(EditEnterWarehouseReq req) {
        EnterWarehouse enterWarehouse = new EnterWarehouse();
        BeanUtil.copyProperties(req,enterWarehouse);
        if(!enterWarehouseService.updateById(enterWarehouse)){
            throw new ErrorDataException();
        }
        req.getList().forEach(detail ->{
            if(!enterWarehouseDetailService.updateById(detail)){
                throw new ErrorDataException();
            }
        });
        if(!req.getDelList().isEmpty()){
            req.getDelList().forEach(del -> enterWarehouseDetailService.removeById(del));
        }
        if(!req.getAddList().isEmpty()){
            req.getAddList().forEach(add -> {
                ProductInfo info = scmWmsUtils.queryProductInfo(add.getExitNum(), add.getId());
                EnterWarehouseDetail detail = new EnterWarehouseDetail();
                detail.setEnterWarehouseSn(req.getEnterWarehouseSn());
                detail.setStorageType(StorageTypeEnum.enterwarehouse);
                detail.setApplyTime(LocalDateTime.now());
                detail.setUnit(info.getUnit());
                detail.setProductSn(info.getProductSn());
                detail.setGoodsModelId(info.getGoodsModelId());
                detail.setProductNumber(BigDecimal.valueOf(add.getExitNum()));
                detail.setPmId(req.getPmId());
                detail.setEnterStatus(EnterStatusEnum.handle);
                if(!enterWarehouseDetailService.save(detail)){
                    throw new ErrorDataException();
                }
            });
        }
        return true;
    }
}
